home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 6
/
Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso
/
016a
/
drivex0.zip
/
DRIVEXX.TXT
< prev
next >
Wrap
Text File
|
1991-11-01
|
27KB
|
574 lines
(********************************************************************)
(* UNIT DRIVExx *)
(* *)
(* Version 1.01 *)
(* *)
(* Copyright (C) 1991 by NativSoft Computing *)
(* *)
(* 1155 College Ave *)
(* Adrian, MI 49221 *)
(* (517) 265-6080 *)
(* CIS [71160,1045] *)
(* *)
(* Written by: Charles B. Little, Ph.D. *)
(* Version: 1.01 *)
(* Revision Date: 1 November 1991 *)
(* Language: Turbo Pascal v6 *)
(* *)
(* ALL RIGHTS RESERVED *)
(* *)
(********************************************************************)
INTRODUCTION:
DRIVExx is a collection of tools, written in Turbo Pascal v6, for dealing
with block devices in a DOS environment. To the best of our knowledge, no
such tools exist in any "professional" programming toolboxes, in any
programming language. The tools available here will allow any Pascal
programmer who uses disk I/O to gain that extra measure of control over his
or her application. At the very least they will have the ability to
prevent access of a phantom drive so their nice user interface won't get
overwritten by non-interceptable DOS messages like "Insert a disk..."
While it may not be the last word on the subject, DRIVExx works. And just
about everything you'd want your applications to know about drives is
available WITHOUT ACCESSING THEM! The only exceptions to hitting drives
are functions DiskWasChanged and GETDPB: DiskWasChanged will hit a drive
ONLY if the drive supports changeline detection, and GETDPB will hit the
disk only if you tell it to. Naturally, it is perfectly safe for GETDPB to
hit a removable drive that does not have a disk in it.
Much of the required information is available only in undocumented DOS
functions and data structures. Wherever a documented function will return
the same information, however, the undocumented function is still used as a
redundancy check. Indeed, the source code for DRIVExx is probably at least
50% longer than need be due to extensive interlocking redundancy checking.
All of the features of DRIVExx are demonstrated in the demo program
DRVDEMO.PAS. The only exception to this is function MakeActive, whose
description below should make clear why it is impractical to include it in
DRVDEMO.
CONDITIONS:
DRIVExx.TPU is not free. IT IS SHAREWARE AND IT IS COPYRIGHTED. If you
use it you are expected to pay for it -- that's how shareware works.
However, you only pay the registration fee. Absolutely no royalties are
expected or will be sought if you use it in any commercial program. It
comes with the usual caveats (spelled out in the REGISTRATION/ORDER FORM)
about suitability, limits of liability, etc.
The registration fee as of 1 November 1991 is $15. Commented source code
may be made available if demand is great enough, but fees and distribution
agreements have not yet been established. Fees for DRIVExx should be
accompanied by a completed REGISTRATION/ORDER FORM, found on the last page
of this file.
Since DRIVExx has not been tested it on every conceivable platform and
under every flavor of DOS out there, special consideration (i.e., fee
waiver or free upgrades) will be given to any user who reports bugs or
anomalous behavior, and can suggest a fix.
If you like it and find it useful you may distribute DRIVExx freely as long
as all files in the original LZH file are distributed. Those files are:
DRIVExx.TXT (this file)
DRIVExx.TPU size = 20528, date = 11/1/91, time = 6:00pm
DRVDEMO.PAS size = 10034, date = 11/1/91, time = 6:00pm
DRVDEMO.EXE size = 28192, date = 11/1/91, time = 6:00pm
Phone support and (cheap) upgrades will be available to registered users
ONLY.
REQUIREMENTS:
DOS version: MS-DOS 3.0 to 5.0
Hardware: XT, AT, or PS/2 compatible PC.
ACKNOWLEDGEMENTS:
MS-DOS is a registered trademark of the Microsoft Corporation
PC Tools Deluxe is a registered trademark of Central Point Software
NCACHE is a registered trademark of Symantec Corporation
Stacker is a registered trademark of Stac Electronics
DESCRIPTION OF TYPES AND GLOBAL VARIABLES
Only one variable type is defined in the Interface section of DRIVExx.
"FakeDPB" is so named because it does not conform to the real DPB structure
as defined under any single version of DOS. It nevertheless contains most
useful information found in the actual DPB after DOS 3.0.
TYPE
FakeDPB = record
ddunitnum : byte; Unit number within device driver
bytespersex : word; Bytes/sector
sexperclust : byte; Sectors/cluster
numFATS : byte; Number of FAT copies on the disk
RootdirEnts : word; Number of root directory entries
FirstDataSec : word; First data sector on the disk
numclusts : word; Number of data clusters on the disk
sexperFAT : word; Sectors in each FAT
mediabyte : byte; Media descriptor byte
accessflag : byte; 0 if drive was accessed since bootup
RootdirSex : word; Number of sectors in root directory
end;
Global Variables:
DOSVER : real
The currently running DOS version, expressed as a real number. This
information is critical to the proper operation of DRIVExx, since many
internal DOS data structures vary from one DDOS version to another.
You should be aware that some DOS versions do not return a value to
this function equal to the product's version number. For example,
under MS DOS version 5 this function will return DOSVER = 5.00, but
under DR DOS version 5 it will return DOSVER = 3.30! These *known*
situations with non-MS versions are dealt with, but full compatibility
is assured ONLY under MS-DOS or IBM's PC-DOS. Of course, even MS-DOS
prior to version 5 can fool DRIVExx into a fatal error because
Microsoft did not provide a function in these versions that "sees
through" fake version numbers set by SETVER! DRIVExx assumes that
DOSVER returns the TRUE version number; it can be ASSURED of finding
the correct DOS version only with MS-DOS 5.
DRDOS : boolean
DRIVExx uses an undocumented (but DR-approved) function call to
determine SPECIFICALLY whether DR DOS is running. This is important
because DR DOS 5 is really a clone of MS DOS 3.3, with some internal
data structures modified to accommodate volumes larger than 32M (ala
Compaq DOS 3.31). Thus, programs running under DR DOS 5 can't count
on internal (undocumented) data structures to be the same as in any
SINGLE version of MS DOS. We also know that ASSIGN and SUBST are not
reported the way they are in MS DOS, and suspect that other situations
of "aliased" drives may be ambiguously reported under this OS.
Therefore, when running under DR DOS we recommend calling the generic
DriveIsAliased function and not bothering to try to distinguish
between SUBST, ASSIGN, JOIN, NETWORK and IFS (installable file
system). See function "DriveIsAliased" in the next section.
DriveError : longint
A global error code that is the sum of one or more error codes
described below. A value of zero means no errors were detected during
execution of the main procedure, UpdateDrives. Only three errors will
cause immediate exit from UpdateDrives: Error 00001 - wrong DOS
version (or OS/2), Error 00002 - not enough memory to create the
variable DRIVES^, and Error 00004 - failure to find the address of
DOS's List-of-Lists. All of these errors will result in all booleans
set to false and all strings set to null, because they make it
impossible to continue processing UpdateDrives.
Less serious errors arise mostly as a result of redundancy checking on
undocumented DOS functions and data structures, thus execution may
continue and multiple errors can be reported. It would then be up to
the programmer or user to determine how to proceed. In general it
would not be wise to allow a program to proceed if DriveError were
non-zero.
The procedure ShowDriveError described at the end of the next section
will interpret the individual error codes summed in DriveError.
ANY NON-ZERO DRIVEERROR SHOULD BE REPORTED TO NATIVSOFT IMMEDIATELY!
InternalFloppies : byte
The number of BIOS-driven floppy drives, deduced from the equipment
list word at $0000:$0410.
NumBlockDevs : byte
The number of block devices, most accurately described as the number
of Drive Parameter Blocks set up during the processing of the
CONFIG.SYS file. This is NOT ALWAYS the same as NumLogicalDrives
since a logical drive can be "created" using SUBST or JOIN but won't
necessarily have a DPB associated with it. Every block device also
has a device driver associated with it, whose address can be found in
the drive's DPB.
DevDrvrChainValid : boolean;
Some software, notably Norton's NCACHE, seems to relocate device
drivers for all system disk drives. As a consequence, function
DriveIsSwapped and variable BootableDrives are unreliable when NCACHE
is loaded. However, DriveIsSwapped and BootableDrives are both
reliable if the variable DevDrvrChainValid is TRUE.
This is a problem that will be addressed in a future release of
DRIVExx -- as soon as non-disclosure agreements are signed with
Symantec.
NumLogicaldrives : byte
A short explanation of this variable is that NumLogicalDrives is
simply the length of the string AllLogicalDrives, described below.
AllLogicaldrives : string[26]
Logical drives are those associated with real drives, virtual drives,
phantom drives (including phantom drives created with DRIVER.SYS), and
"aliased" drives created by SUBST or JOIN. For example, a two floppy
system with a hard disk partitioned into C: and D: and a RAMdisk set
up as E: would have 5 logical drives, A: thru E:, and AllLogicalDrives
would be the string 'ABCDE'. Having the statement LASTDRIVE=Y in your
CONFIG.SYS file and executing SUBST P: C:\DOS would give you 6 logical
drives, A: thru E: AND P:, and thus AllLogicalDrives would have the
value 'ABCDEP'. Note that P: is a "logical" drive, so
NumLogicalDrives is 6 (A: thru E:, and P:), but it does not have a DPB
associated with it so NumBlockDevs is 5 (A: thru E: only).
BootableDrives : string[26]
Driveletters of BIOS-driven drives, minus any phantom or aliased
drives. The purpose in defining this variable was to compile a list
of drives available AT THE TIME UPDATEDRIVES IS RUN from which one
might be able to boot the system. This would exclude any device
driven drive installed in CONFIG.SYS, but would include floppy disk B:
if a REAL floppy drive exists, as well as hard disk partitions other
than C:. It would also exclude the second of two physical hard disks
if two were installed.
There are circumstances under which this variable will be a null
string. See "DevDrvrChainValid" above.
Floppies, Hards : string[26]
Strings of uppercase driveletters representing the drive types
indicated.
BiosDateString : string[8]
The date of the system BIOS, in a non-zero-padded format: mm/dd/yy.
Example 3/3/89 (not 03/03/89).
DevDrvrChainValid : boolean;
This variable will almost ALWAYS be TRUE, in which case you needn't
pay attention to it. When this variable is FALSE, however, it just
means that some program has been messing around with the addresses of
the block device drivers. In this case "BootableDrives" should be a
null string, and the function DriveIsSwapped should be ignored since
its returned value will be meaningless. What programs are capable of
this? The only one (now) know to do this is Norton's NCACHE.
DESCRIPTION OF PROCEDURES AND FUNCTIONS
This section describes all procedures and functions declared in the
INTERFACE of unit DRIVExx. All functions below that require a character
argument will accept either uppercase or lowercase driveletters; characters
other than letters of the alphabet will ALWAYS cause boolean functions to
return FALSE since each of these functions first calls DrivExists, which of
course will return FALSE in such cases.
PROCEDURE UpdateDrives
Creates or updates the DRIVES^ array. This "dynamic" array is
allocated on the heap and consists of one element for each valid drive
(a total of NumLogicalDrives elements). Because the dynamic array
technique requires range checking to be OFF, it's especially important
not to use an invalid drive letter as an array index, as this may send
your program into outer space. This is easily accomplished by not
allowing direct access to DRIVES^ by keeping it in the IMPLEMENTATION
section! All information in this array is accessible only through the
functions described below. This is about as close to OOP as I ever
care to get, thank you very much!
UpdateDrives is called in the unit initialization, and need not be
called directly unless your program shells out to DOS. It should be
called upon return to your main program to guard against a situation
in which a user might have SUBSTed or JOINed a drive, or accessed a
phantom drive, while shelled out.
FUNCTION DrivExists(drv:char) : boolean
Self explanatory. Returns FALSE if the drive doesn't exist. If you
type Q: at the DOS prompt and get the message "invalid drive
specification", you'll also get FALSE with DrivExists(Q). Conversely,
if you don't get "invalid drive specification" then DrivExists will
return TRUE. Simple.
FUNCTION DriveisNormal(drv:char) : boolean
This function will return FALSE in only a few situations:
1) Returns FALSE for phantom, aliased and NONDOS drives. It is
expedient for many applications to DEFINE these types of drives
as non-normal.
2) Returns FALSE for any drive that does not support Interrupt 21
Function $4408 calls. This is somewhat arbitrary, but in my
experience the only block devices that do not support $4408 calls
are NONDOS drives (see next function below).
3) Returns FALSE if, at any time during the execution of
UpdateDrives, a DOS or BIOS function call returns "invalid
function" for a drive that is supposed to support that function.
In this case you will almost certainly see a non-zero value for
DriveError that will diagnose the problem.
FUNCTION DriveisNONDOS(drv:char) : boolean
NONDOS drives are somewhat rare in my experience. However, if you use
a PC running IBM AS/400 or System38 emulation, you might have virtual
drives created for "PC-Support". These are the only examples of
NONDOS drives with which I am familiar. Just trying to access such a
drive is dangerous, and trying to run DOS's CHKDSK on one will usually
get you a "Memory allocation error. System halted" message. While
there's not much we can do to teach IBM to write decent block device
drivers, DRIVExx should make their lousy code easier to live with by
avoiding it altogether.
FUNCTION DriveisRemovable(drv:char) : boolean
Self explanatory. Again, we have yet to see it incorrectly classify a
drive. The TYPE of removable drive can be found with function
RemovableDriveType described below.
FUNCTION RemovableDrivetype(drv:char) : byte
Returns:
-3 : Int $13 function $08 failed
-2 : Int $13 function $08 returned value not in range 0-4
-1 : Int $13 function $08 returned 0 for unknown reason
0 : type can't be determined (no error) or drive is NOT
removable
1 : 5.25" 360K
2 : 5.25" 1.2M
3 : 3.5" 720K
4 : 3.5" 1.44M
5 : 3.5" 2.88M
6 : TAPE
7 : Bernoulli
FUNCTION DriveisPhantom(drv:char) : boolean
This function is somewhat problematic for DOS versions PRIOR to 3.2,
in that "phantomness" in these environments has to be decided
primarily based on the value of the byte at $0000:$0504. In one-
floppy systems this byte is 0 if the single floppy was most recently
accessed as A:, or 1 if it was most recently accessed as B:. However,
some relatively ill-behaved programs such as PC Tools Deluxe version 6
will change this memory location to $FF in certain situations,
rendering this phantom-finding method ineffective. Since DOS 3.2
phantom-finding has been safe and straightforward, so only well-
behaved and documented functions are used when running under these
newer operating systems.
PROCEDURE MakeDriveActive(drv:char)
Whenever a phantom drive exists -- whether it's drive B: in a
one-floppy system, or one created by DRIVER.SYS -- this procedure will
make it active so you don't see the obnoxious "Insert diskette... "
message when you try to access it. This message is NOT interceptable;
the only way to avoid it is to avoid trying to access a phantom drive.
This procedure does that, AND ALSO CALLS UpdateDrives WHEN IT'S
FINISHED!!
FUNCTION DriveMappedTo(drv:char) : char
If drv is a removable drive and is currently classified as phantom,
this function will return the uppercase driveletter of the physical
drive to which the phantom is currently mapped.
FUNCTION DriveisSubsted(drv:char) : boolean
FUNCTION DriveisJoined(drv:char) : boolean
FUNCTION DriveisAssigned(drv:char) : boolean
FUNCTION DriveisNetwork(drv:char) : boolean
FUNCTION DriveisIFS(drv:char) : boolean
FUNCTION DriveisAliased(drv:char) : boolean
These are fairly self-explanatory. The last function in this group,
DriveIsAliased, is a shortcut that returns true if a drive is SUBSTed,
JOINed, ASSIGNed, NETWORK or IFS (installable file system). These
functions have been tested extensively for SUBSTed, JOINed and
ASSIGNed drives, but not for NETWORK or IFS drives as I have no access
to such drives.
If DriveIsAliased returns true for a drive, there is little RELIABLE
information that can be obtained for it other than whether it's device
driven or swapped, as DRVDEMO shows.
Under DR DOS, only DriveIsAliased should be called, since the other
"aliased" functions may not operate correctly. We KNOW this to be the
case for ASSIGN and SUBST, but have not checked it out for NETWORK and
IFS drives.
FUNCTION DriveisDeviceDriven(drv:char) : boolean
Any drive that's run by a device driver installed in the CONFIG.SYS
file will return TRUE here. This is true for RAM disks as well as for
REAL physical drives, like some 1.2M external 5.25" drives on IBM PS/2
machines.
FUNCTION DriveisSwapped(drv:char) : boolean
Useful for systems that have a real drive swapped with a device-driven
drive (such as STACKER volumes), especially if one of the swapped
drives is your bootable hard disk partition.
See variable "DevDrvrChainValid" above for limitations.
FUNCTION DriveisHard(drv:char) : boolean
FUNCTION DriveisRAMDisk(drv:char) : boolean
FUNCTION DriveisOtherfixed(drv:char) : boolean
These are the only categories of non-removable drives; the functions
are also self explanatory. We have yet to see a non-removable drive
that couldn't be classified as either hard or RAM disk, but function
DriveisOtherfixed is included to take care of this possibility.
Instead of having three BOOLEAN functions for the three drive types,
we COULD have defined a single BYTE function, NONRemovableType that
returns 1 for hard disks, 2 for RAM disks and 3 for "other". In my own
applications, though, I find it more convenient to have a single,
direct test for a hard disk.
FUNCTION ChangeLineSupported(drv:char) : boolean
This should return true ONLY for removable drives, and then only if
the device driver for the drive says it supports change line
detection.
FUNCTION DiskWasChanged(drv:char) : boolean
This functions hits the disk only if there's support for changeline
detection. And it makes no difference whether there's a disk in the
drive -- no errors are generated if there isn't a disk in the drive.
FUNCTION DriveSize(drv:char) : longint
This function returns:
-1 : if there's an error calculating disk size from DPB data
0 : usually only for a removable drive that hasn't been accessed, and
so has no valid DPB data to use
> 0 : disk size IN BYTES; if the disk is REMOVABLE, DriveSize returns
the size of last disk accessed in drive
FUNCTION CurrentDir(drv:char) : pathstr
Returns the currently logged directory for the specified drive as a
complete path, including driveletter, colon and final backslash, all
in uppercase letters. If the drive doesn't exist a null string is
returned.
FUNCTION DefaultDrive : char
Identifies the current default drive as an uppercase letter.
FUNCTION GETDPB(drv:char; var d:fakeDPB; hit:boolean) : boolean;
Puts useful drive data from DPB into d. If HIT is TRUE, the function
will hit the disk to update the DPB data in memory. Otherwise it will
return data already in memory, usually for the last disk that was
accessed in the drive. GETDPB returns FALSE if problems were
encountered (drv is an invalid drive, no disk in drive when HIT is set
to TRUE, etc.) and all fields of d will be zeroed out.
PROCEDURE ShowDriveError;
Shows and interprets errors using global DriveError variable.
PRODUCT SUPPORT
Support is available TO REGISTERED USERS ONLY at (517)-265-6080 after 5pm
Eastern (weekdays), or by U.S. Mail. Bug reports and/or suggestions for
improvement are always welcome from anyone. However, no collect calls can
be accepted.
REGISTRATION/ORDER FORM
COMPANY NAME: _______________________________________________________
ADDRESS: _______________________________________________________
_______________________________________________________
_______________________________________________________
WARRANTY DISCLAIMER:
THIS PROGRAM IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR
REASON. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
PROGRAM IS WITH THE CUSTOMER. THE CUSTOMER SHALL ASSUME THE ENTIRE
COST OF SERVICING, REPAIR, AND CORRECTION.
IN NO EVENT SHALL NativSoft BE LIABLE TO THE CUSTOMER FOR ANY DAMAGES,
INCLUDING LOST PROFITS, LOST SAVINGS, OR OTHER INCIDENTAL OR
CONSEQUENTIAL DAMAGES, ARISING OUT OF THE USE OR INABILITY TO USE SUCH
PROGRAM, EVEN IF NativSoft OR AN AUTHORIZED REPRESENTATIVE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM BY
ANOTHER PARTY.
I HAVE READ THE ABOVE AGREEMENT AND BY MY SIGNATURE BELOW ACCEPT ITS
TERMS.
NAME: _______________________ SIGNATURE: ________________________
_____ Copies of DRIVExx.TPU @ $15.00 ea : $_______
(Michigan Residents add 4% sales tax) : $_______
TOTAL : $_______
Payment by check or money order in U.S. Dollars only.
Make check or money order payable to NativSoft Computing.
Mail this completed REGISTRATION form with payment to:
NativSoft Computing
1155 College Ave.
Adrian, MI 49221